/**
 * @file fsm.h
 * @brief The finite state machine for ports on boundary and ordinary clocks.
 * @note Copyright (C) 2011 Richard Cochran <richardcochran@gmail.com>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */
#ifndef HAVE_FSM_H
#define HAVE_FSM_H

/** Defines the state of a port. */
enum port_state {
	PS_INITIALIZING = 1,			// 这是 PTP 协议的起始状态，设备在启动时进入此状态。
	PS_FAULTY,						// 如果设备检测到严重错误，比如通信故障或配置错误，它可能会进入故障状态。
	PS_DISABLED,
	PS_LISTENING,					// 设备在此状态下接收来自其他 PTP 设备的同步消息，但不发送消息。
	PS_PRE_MASTER,					// 设备在此状态下开始尝试成为通信域中的主时钟。
	PS_MASTER,						// 成功成为主时钟的设备进入此状态，负责发送同步信息给其他设备。
	PS_PASSIVE,						// 设备在此状态下不参与同步过程，可能是由于配置或策略原因。
	PS_UNCALIBRATED,				// 发现有多个master端口在同一个domain中
	PS_SLAVE,						// 设备接收主时钟的同步信息，并根据这些信息调整自己的时钟。
	PS_GRAND_MASTER, /*non-standard extension*/
};

/** Defines the events for the port state machine. */
enum fsm_event {
	EV_NONE,
	EV_POWERUP,						// 上电事件：进入 INITIALZING状态
	EV_INITIALIZE,					// 任何状态 发生 INITIALIZE 进入 INITIALZING 状态
	EV_DESIGNATED_ENABLED,			// DISABLE 状态之下 执行 EV_DESIGNATED_ENABLED 进入
	EV_DESIGNATED_DISABLED,			// LISTENING/UNCALIBRATED/SLAVE（PRE_MASTER/MASTER/PASSIVE） 发生 EV_DESIGNATED_DISABLED 进入 DISABLE
	EV_FAULT_CLEARED,				// FAULTY 发生 EV_FAULT_CLEARED 进入 INITIALING
	EV_FAULT_DETECTED,				// LISTENING/UNCALIBRATED/SLAVE（PRE_MASTER/MASTER/PASSIVE） 发生 EV_FAULT_DETECTED 进入 DISABLE
	EV_STATE_DECISION_EVENT,		// LISTENING/UNCALIBRATED/SLAVE（PRE_MASTER/MASTER/PASSIVE） 互相切换
	EV_QUALIFICATION_TIMEOUT_EXPIRES,		// PRE_MASTER 切换到 MASTER 的事件
	EV_ANNOUNCE_RECEIPT_TIMEOUT_EXPIRES,	// 接收ANNOUNCE 超时，切换到MASTER 
	EV_SYNCHRONIZATION_FAULT,		// SLAVE 接收 Sync超时，切换到 UNCALIBRATED 
	EV_MASTER_CLOCK_SELECTED,		// 在 UNCALIBRATED状态下发现MASTER 切换回 SLAVE 
	EV_RS_MASTER,					// 
	EV_RS_GRAND_MASTER,
	EV_RS_SLAVE,
	EV_RS_PASSIVE,
};

/**
 * Run the state machine for a BC or OC port.
 * @param state  The current state of the port.
 * @param event  The event to be processed.
 * @param mdiff  Whether a new master has been selected.
 * @return       The new state for the port.
 */
enum port_state ptp_fsm(enum port_state state, enum fsm_event event, int mdiff);

/**
 * Run the state machine for a slave only clock.
 * @param state  The current state of the port.
 * @param event  The event to be processed.
 * @param mdiff  Whether a new master has been selected.
 * @return       The new state for the port.
 */
enum port_state ptp_slave_fsm(enum port_state state, enum fsm_event event,
			      int mdiff);

#endif
